package de.blinkt.openvpn.advancedconnection;

import java.util.Arrays;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import de.blinkt.openvpn.VpnProfile;

class AdvancedConnectionSettingsPresenter implements OnSharedPreferenceChangeListener {

	private class PortPrefChangeListener implements OnPreferenceChangeListener {
		@Override
		public boolean onPreferenceChange(Preference preference, Object newValue) {

			if (newValue == null || ((String) newValue).length() == 0) {
				return false;
			} else {
				int port;
				try {
					port = Integer.parseInt(newValue.toString());
					if (port <= 0 || port > Short.MAX_VALUE) {
						return false;
					} else {
						return true;
					}
				} catch (NumberFormatException e) {
					return false;
				}
			}
		}

		
	}

	private class ServerPrefChangeListener implements OnPreferenceChangeListener {
		@Override
		public boolean onPreferenceChange(Preference preference, Object newValue) {
			if (newValue == null || ((String) newValue).length() == 0) {
				return false;
			} else {
				return true;
			}
		}
	}

	private AdvancedConnectionSettingsView mView;

	public AdvancedConnectionSettingsPresenter(AdvancedConnectionSettingsView view, Activity activity) {
		mView = view;
	}

	public void loadSettings(VpnProfile model) {
		
		if(model != null){
			if(model.mUseUdp){
				mView.getProxyType().setValue(VpnProfile.PROXY_TYPE_NONE);
			} else {
				
				mView.getRestrictReconnectToNetworks().setChecked(model.mRestrictReconnectToNetworks);
				
				if (VpnProfile.PROXY_TYPE_HTTP.equals(model.mProxyType)) {
					mView.getProxyType().setValue(VpnProfile.PROXY_TYPE_HTTP);
					mView.getHttpProxyServerAddress().setText(model.mProxyServerAddress);
		
					if (model.mProxyServerPort > 0) {
						mView.getHttpProxyServerPort().setText("" + model.mProxyServerPort);
					} else {
						mView.getHttpProxyServerPort().setText("");
					}
		
				} else if (VpnProfile.PROXY_TYPE_SOCKS.equals(model.mProxyType)) {
					mView.getProxyType().setValue(VpnProfile.PROXY_TYPE_SOCKS);
					mView.getSocksProxyServerAddress().setText(model.mProxyServerAddress);
		
					if (model.mProxyServerPort > 0) {
						mView.getSocksProxyServerPort().setText("" + model.mProxyServerPort);
					} else {
						mView.getSocksProxyServerPort().setText("");
					}
		
				} else {
					mView.getProxyType().setValue(VpnProfile.PROXY_TYPE_NONE);
				}
			}
		} else {
			mView.getRestrictReconnectToNetworks().setChecked(false);
		}
		
		updateView();

	}

	public void saveSettings(VpnProfile model) {

		
		model.mRestrictReconnectToNetworks = mView.getRestrictReconnectToNetworks().isChecked();
		
		model.mProxyType = mView.getProxyType().getValue();

		// migrate from prefs to VPNProfile
		if (VpnProfile.PROXY_TYPE_HTTP.equals(mView.getProxyType().getValue())) {
			model.mProxyServerAddress = mView.getHttpProxyServerAddress().getText();
			model.mProxyServerPort = Integer.parseInt(mView.getHttpProxyServerPort().getText());
		} else if (VpnProfile.PROXY_TYPE_SOCKS.equals(mView.getProxyType().getValue())) {
			model.mProxyServerAddress = mView.getSocksProxyServerAddress().getText();
			model.mProxyServerPort = Integer.parseInt(mView.getSocksProxyServerPort().getText());
		} else {
			model.mProxyServerAddress = "";
			model.mProxyServerPort = 0;
		}

	}


	private void updateView() {
		
		mView.getProxyType().setSummary(mView.getProxyType().getValue());
		
		mView.getHTTPProxyGroup().setEnabled(VpnProfile.PROXY_TYPE_HTTP.equals(mView.getProxyType().getValue()));
		mView.getSOCKSProxyGroup().setEnabled(VpnProfile.PROXY_TYPE_SOCKS.equals(mView.getProxyType().getValue()));
		mView.getHttpProxyServerPort().setSummary(VpnProfile.PROXY_TYPE_HTTP.equals(mView.getProxyType().getValue()) ? mView.getHttpProxyServerPort().getText() : "");
		mView.getHttpProxyServerAddress().setSummary(VpnProfile.PROXY_TYPE_HTTP.equals(mView.getProxyType().getValue()) ? mView.getHttpProxyServerAddress().getText() : "");
		mView.getSocksProxyServerPort().setSummary(VpnProfile.PROXY_TYPE_SOCKS.equals(mView.getProxyType().getValue()) ? mView.getSocksProxyServerPort().getText() : "");
		mView.getSocksProxyServerAddress().setSummary(VpnProfile.PROXY_TYPE_SOCKS.equals(mView.getProxyType().getValue()) ? mView.getSocksProxyServerAddress().getText() : "");
	
		
		mView.getSelectRestrictedNetworks().setEnabled(mView.getRestrictReconnectToNetworks().isChecked());
		
		mView.getHTTPProxyGroup().setSummary(VpnProfile.PROXY_TYPE_HTTP.equals(mView.getProxyType().getValue())  ? buildHTTPProxySummary() : "");
		mView.getSOCKSProxyGroup().setSummary(VpnProfile.PROXY_TYPE_SOCKS.equals(mView.getProxyType().getValue()) ? buildSOCKSProxySummary() : "");
		
		
		
	}

	private String buildSOCKSProxySummary() {
		if(mView.getSocksProxyServerAddress().getText() != null && mView.getSocksProxyServerPort().getText() != null ){
			return mView.getSocksProxyServerAddress().getText() + ":" + mView.getSocksProxyServerPort().getText().trim();
		} else {
			//TODO: Externalize
			return "Not Configured";
		}
	}

	private String buildHTTPProxySummary() {
		if(mView.getHttpProxyServerAddress().getText() != null && mView.getHttpProxyServerPort().getText() != null ){
			return mView.getHttpProxyServerAddress().getText() + ":" + mView.getHttpProxyServerPort().getText().trim();
		} else {
			//TODO: Externalize
			return "Not Configured";
		}	}

	public void initView() {
		// initial view state
		// Proxy type = none
		// HTTP options cleared
		// HTTP group hidden
		// SOCKS options cleared
		// SOCKS group hidden
		registerChangeHandlers();
		
		updateView();
	}

	private void registerChangeHandlers() {
		mView.getProxyType().setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
			@Override
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				if (Arrays.asList(new String[] { VpnProfile.PROXY_TYPE_NONE, VpnProfile.PROXY_TYPE_HTTP, VpnProfile.PROXY_TYPE_SOCKS }).indexOf(newValue) < 0) {
					return false;
				} else {
					return true;
				}
			}
		});

		mView.getHttpProxyServerAddress().setOnPreferenceChangeListener(new ServerPrefChangeListener());

		mView.getSocksProxyServerAddress().setOnPreferenceChangeListener(new ServerPrefChangeListener());

		mView.getSocksProxyServerPort().setOnPreferenceChangeListener(new PortPrefChangeListener());

		mView.getHttpProxyServerPort().setOnPreferenceChangeListener(new PortPrefChangeListener());

		
		//TODO: Verify no leak
		mView.getRestrictReconnectToNetworks().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);

		
		
	}

	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
		updateView();
	}




}
